Fix for TALOS-2026-2358
authorAlex Tutubalin <lexa@lexa.ru>
Sun, 1 Mar 2026 16:54:16 +0000 (19:54 +0300)
committerGuilhem Moulin <guilhem@debian.org>
Wed, 29 Jul 2026 01:53:35 +0000 (03:53 +0200)
Origin: https://github.com/LibRaw/LibRaw/commit/b9809e410d07ca7bf408e6d036615fb34f8c47cc
Bug: https://talosintelligence.com/vulnerability_reports/TALOS-2026-2358
Bug-Debian: https://bugs.debian.org/1133845
Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2026-20889

Gbp-Pq: Name CVE-2026-20889.patch

src/decoders/unpack_thumb.cpp
src/x3f/x3f_parse_process.cpp
src/x3f/x3f_utils_patched.cpp

index df30da16296cdebe4c727a7f05c830034d5e31c1..f79b0bb9f48fc00c1996852db8bb4ff4e44b34b2 100644 (file)
@@ -387,6 +387,8 @@ int LibRaw::unpack_thumb(void)
       {\r
         x3f_thumb_loader();\r
         SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD);\r
+               if (!T.twidth && !T.theight)\r
+                       return LIBRAW_NO_THUMBNAIL;\r
         return 0;\r
       }\r
 #endif\r
index 354e4673795aa4d778944ed12e131646029873b4..9742c8e63ad6c2883991d5946b2a75168ec6dd63 100644 (file)
@@ -322,6 +322,7 @@ void LibRaw::x3f_thumb_loader()
 {
   try
   {
+    INT64 checked_size = x3f_thumb_size(); // This value was checked at upper level?
     x3f_t *x3f = (x3f_t *)_x3f_data;
     if (!x3f)
       return; // No data pointer set
@@ -339,12 +340,24 @@ void LibRaw::x3f_thumb_loader()
     imgdata.thumbnail.tcolors = 3;
     if (imgdata.thumbnail.tformat == LIBRAW_THUMBNAIL_JPEG)
     {
-      imgdata.thumbnail.thumb = (char *)malloc(ID->data_size);
+         INT64 alloc_size = ID->data_size;
+         if ((alloc_size > 2 * checked_size) || (alloc_size > 1024LL * 1024LL * LIBRAW_MAX_THUMBNAIL_MB))
+                 throw LIBRAW_EXCEPTION_TOOBIG;
+         if(alloc_size < 64LL)
+        throw LIBRAW_EXCEPTION_IO_CORRUPT;
+
+         imgdata.thumbnail.thumb = (char *)malloc(ID->data_size);
       memmove(imgdata.thumbnail.thumb, ID->data, ID->data_size);
       imgdata.thumbnail.tlength = ID->data_size;
     }
     else if (imgdata.thumbnail.tformat == LIBRAW_THUMBNAIL_BITMAP)
     {
+      INT64 alloc_size = INT64(ID->columns) * INT64(ID->rows) * 3LL;
+         if ((alloc_size > 2 * checked_size) ||
+          (alloc_size > 1024LL * 1024LL * LIBRAW_MAX_THUMBNAIL_MB)) throw LIBRAW_EXCEPTION_TOOBIG;
+      if (alloc_size < 64LL)
+        throw LIBRAW_EXCEPTION_IO_CORRUPT;
+
       imgdata.thumbnail.tlength = ID->columns * ID->rows * 3;
       imgdata.thumbnail.thumb = (char *)malloc(ID->columns * ID->rows * 3);
       char *src0 = (char *)ID->data;
@@ -361,7 +374,10 @@ void LibRaw::x3f_thumb_loader()
   }
   catch (...)
   {
-    // do nothing
+    // no rethrow: handled at upper level
+    imgdata.thumbnail.twidth = 0;
+    imgdata.thumbnail.theight = 0;
+    imgdata.thumbnail.tcolors = 0;
   }
 }
 
index 6b20b9074e28870b9ad123ac105fabcf80c8ea7a..21c7ab16f34daca1e20662b089eb085bcdf72cf1 100644 (file)
@@ -1221,7 +1221,14 @@ static uint32_t read_data_block(void **data, x3f_info_t *I,
   if (fpos + size > I->input.file->size())
     throw LIBRAW_EXCEPTION_IO_CORRUPT;
 
+  // All known files from real cameras are many times smaller than 1 GB, so the hard limit is OK here.
+
+  if(size > 1024*1024*1024)
+    throw LIBRAW_EXCEPTION_ALLOC;
+
   *data = (void *)malloc(size);
+  if (!*data)
+         throw LIBRAW_EXCEPTION_ALLOC;
 
   GETN(*data, size);